﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using modBusTest;
using System.IO.Ports;
using Modbus.Device;
using Modbus.Extensions;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Xml;
using System.Xml.Serialization;



namespace ModbusTestTool
{

    
    public partial class MainWindow : Form
    {
        
        //ParamWindows paramWindow;
        SerialPort port;
        state currentState;
        ModbusSerialMaster master;
        List<ParamWindows> ListOfParamwindos = new List<ParamWindows>();
        FileSelector fileselect = new FileSelector();
        public MainWindow()
        {
            
            InitializeComponent();
            this.DragEnter += new DragEventHandler(MainWindow_DragEnter);
            this.DragDrop += new DragEventHandler(MainWindow_DragDrop);
            if (File.Exists("state.xml"))
            {
                Stream inHandle = File.Open("state.xml", FileMode.Open);
                XmlSerializer xIn = new XmlSerializer(typeof(state));
                currentState = (state) xIn.Deserialize(inHandle);
                FileTextBox.Text = currentState.fileName;
                inHandle.Close();
            }
            else
            {
                FileTextBox.Text = @"defaultMap.txt";
                currentState = new state();
                currentState.comPort = "COM3";
                currentState.modbusId = 49;
                currentState.baudSpeed = 11500;
                currentState.testFileName = @"c:\testFile";
            }
            this.FormClosing += new FormClosingEventHandler(MainWindow_FormClosing);
            port = new SerialPort(currentState.comPort, currentState.baudSpeed, Parity.None, 8, StopBits.One);
            master = ModbusSerialMaster.CreateRtu(port);
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Interval = 2000;
            

            FileSelector test = new FileSelector();
            //test.Show();
        }

        void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();
            foreach (ParamWindows paramWindow in ListOfParamwindos)
            {
                string[] errList;
                if ((errList = paramWindow.error()) != null)
                {
                    foreach (string item in errList)
                    {
                        log(DateTime.Now.ToString());
                        log(item);
                    }
                }
            }
            timer1.Start();
        }

        void MainWindow_DragDrop(object sender, DragEventArgs e)
        {
            string[] file = (string[])e.Data.GetData(DataFormats.FileDrop);
            FileTextBox.Text = file[0];
        }

        void MainWindow_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
                e.Effect = DragDropEffects.All;
        }

        void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
 
            Stream outHandle = File.Open("state.xml", FileMode.OpenOrCreate);
            XmlSerializer xOut = new XmlSerializer(typeof(state));
            currentState.fileName = FileTextBox.Text;
            xOut.Serialize(outHandle, currentState);
            ((IDisposable)outHandle).Dispose();
        }

        private void ReadMap_Click(object sender, EventArgs e)
        {
            
            timer1.Start();
            try
            {
                if (!port.IsOpen)
                    port.Open();
            }
            catch (Exception err)
            {
                log(err.Message);
                return;
            }

            foreach (fileSelect item in fileselect.storage)
            {
                ListOfParamwindos.Add(new ParamWindows(currentState.modbusId, master, item.filename, item.outputfile, int.Parse(item.pollRate)));
            }
            
            
            

            foreach (ParamWindows paramWindow in ListOfParamwindos)
            {
                paramWindow.logging = LogBox.Checked;
                // create modbus master


                //paramWindow.setFileName(FileTextBox.Text);
                paramWindow.Show();
                paramWindow.logging = LogBox.Checked;
            }


            //map.writeDirty();
            
        }



        private void log(string message)
        {
            outputBox.Text += message;
            outputBox.Text += Environment.NewLine;
        }

        private void ReadModbus_Click(object sender, EventArgs e)
        {

            //map.getDataFromDevice();
            //return;sdasdas

            foreach (ParamWindows paramWindow in ListOfParamwindos)
            {
                if (paramWindow.IsDisposed)
                {
                    log("Windown is disposed");
                    paramWindow.setFileName(FileTextBox.Text);
                    //return;
                }
            }
            

            //how long it will take to get the data
            //double baudRate = port.BaudRate;
            //double dataBits = port.DataBits + 2;
            //double storageSize = map.storage.Count;
            //paramWindow.updateTimetime =  1000.0/(((baudRate/dataBits)/4.0)/map.storage.Count)+200.0;

            foreach (ParamWindows paramWindow in ListOfParamwindos)
            {
                //paramWindow.updateTimetime = 100;
                //paramWindow.updateTimetime = 100000000;
                paramWindow.Show();
                paramWindow.updateGrid();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            fileselect.Show();
            //PreformTest();
        }

        //private void PreformTest()
        //{
        //    StreamReader inHandle = null;
        //    try
        //    {
        //        if (currentState.testFileName == null)
        //        {
        //            log("Test File Name is Not defined");
        //            return;
        //        }

        //        inHandle = new StreamReader(currentState.testFileName);

        //        string temp;
        //        while ((temp = inHandle.ReadLine()) != null)
        //        {
        //            string[] command = temp.Split(',');

        //            if (command[0] == "w")
        //            {   
                        
        //                mapFields test = null;
        //                test = RegOrName(command);
                        
        //                test.value = command[2];
        //                map.writeDirty();
        //                log("Executed Write Command: " + temp);
        //            }

        //            if (command[0] == "r")
        //            {
        //                map.getDataFromDevice();
        //                mapFields test = test = RegOrName(command);

        //                if (command[2] == "null")
        //                {
        //                    log("Executed Read Command: " + temp);
        //                }
        //                else
        //                {
        //                    if (test.value == command[2])
        //                    {
        //                        log("MATCHES: Executed Read Command: " + temp + " Response is: " + test.value);

        //                    }
        //                    else
        //                    {
        //                        log("DOES NOT MATCH: Executed Read Command: " + temp + " Response is: " + test.value);
        //                    }
        //                }
        //            }

        //        }
        //    }
        //    catch (Exception err)
        //    {
        //        log(err.Message);
        //    }
        //    finally
        //    {
        //        if (inHandle != null)
        //        {
        //            ((IDisposable)inHandle).Dispose();
        //        }
        //    }

        //}
        ///// <summary>
        ///// Function returns reference to register based on name or register number
        ///// </summary>
        ///// <param name="command">The command structure contains register number or name </param>
        ///// <returns></returns>
        //private mapFields RegOrName(string[] command)
        //{
        //    int regNumber;
        //    mapFields test;
        //    if (int.TryParse(command[1], out regNumber))
        //    {
        //        test = map.findParam(regNumber);
        //    }
        //    else
        //    {
        //        test = map.findParam(command[1]);
        //    }
        //    return test;
        //}
    }
    /// <summary>
    /// A Struct to hold current state of the program
    /// </summary>
    public struct state
    {
        public string fileName;
        public string comPort;
        public byte modbusId;
        public int baudSpeed;
        public string testFileName;
    }
    
}
